package com.w.picture.config;

/**
 * @author wzp
 * @since 2024/12/15
 */

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

/**
 * Spring MVC JSON 配置类，用于自定义 Jackson ObjectMapper 的行为。
 */
@Configuration
public class JsonConfig {

    /**
     * 自定义 Jackson ObjectMapper 以解决 Long 类型在序列化为 JSON 时的精度丢失问题。
     *
     * <p>默认情况下，Jackson 在序列化 Long 类型时可能会导致精度丢失，尤其是在 JavaScript 中，
     * 因为 JavaScript 的 Number 类型只能精确表示到 53 位。因此，我们将 Long 类型序列化为字符串，
     * 确保在客户端（如浏览器）中不会出现精度丢失的问题。</p>
     *
     * @param builder Jackson2ObjectMapperBuilder 构建器，用于创建和配置 ObjectMapper 实例。
     * @return 配置好的 ObjectMapper 实例。
     */
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        // 创建 ObjectMapper 实例，禁用 XML 映射功能（因为我们只处理 JSON）
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();

        // 创建一个新的 SimpleModule 来注册自定义序列化器
        SimpleModule module = new SimpleModule();

        // 注册 Long 类型及其原始类型（即 long 基本数据类型）的序列化器为 ToStringSerializer
        // 这样可以确保 Long 类型在序列化为 JSON 时被转换成字符串形式，避免精度丢失
        module.addSerializer(Long.class, ToStringSerializer.instance);
        module.addSerializer(Long.TYPE, ToStringSerializer.instance);

        // 将模块注册到 ObjectMapper 中
        objectMapper.registerModule(module);

        return objectMapper;
    }
}
